home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C++ / Applications / PICSee Dust 1.01 / Primary Source / PICSViewerSelection.cpp < prev   
C/C++ Source or Header  |  1995-11-23  |  13KB  |  477 lines

  1. #include "PICSViewerPrivate.h"
  2.  
  3. #include "Marquee.h"
  4. #include "assert_mac.h"
  5. #include "KeyUtils.h"
  6.  
  7. // ---------------------------------------------------------------------------
  8.  
  9. static RGBColor sMarqueeColor;
  10.  
  11. // ---------------------------------------------------------------------------
  12.  
  13. static void _ResizePICSViewerSelection(PICSViewerData *viewer, const Rect *newMarquee);
  14. static void _MovePICSViewerSelection(
  15.     PICSViewerData *viewer,
  16.     Point mouseLoc,
  17.     short offsetH,
  18.     short offsetV);
  19.  
  20. #define MARQUEE_DELAY    2
  21.  
  22. // ---------------------------------------------------------------------------
  23.  
  24. void _SetMarqueeColor(RGBColor *marqueeColor) {
  25.     sMarqueeColor = *marqueeColor;
  26. } // END _SetMarqueeColor
  27.  
  28. // ---------------------------------------------------------------------------
  29.  
  30. /*
  31.     This is the callback routine that is called constantly when
  32.     the user is sizing or dragging the marquee.
  33. */
  34.  
  35. void _TrackUpdateMarquee(const Rect *rectToUpdate, const Rect *currentMarquee) {
  36.     PICSViewerData *viewer;
  37.     
  38.     viewer = _ExtractPICSViewer(FrontWindow());
  39.     
  40.     if (viewer == NULL) {
  41.         SysBeep(10);
  42.         ASSERT(viewer != NULL);
  43.     }
  44.     else {
  45.         _EraseMarquee(viewer, rectToUpdate);
  46.         _SetMarqueeRect(viewer, currentMarquee, true);
  47.     }
  48. } // END _UpdateMouseMarquee
  49.  
  50. // ---------------------------------------------------------------------------
  51.  
  52. /*
  53.     This erases the marquee by CopyBitsing() from the offscreen
  54.     buffer to <rectToErase>. If you pass NULL to <rectToErase>,
  55.     it will use the current marquee's rect.
  56. */
  57.  
  58. void _EraseMarquee(PICSViewerData *viewer, const Rect *rectToErase) {
  59.     Rect srcDrawRect, destDrawRect;
  60.     RGBColor saveBack, backColor;
  61.  
  62.     if (rectToErase != NULL)
  63.         destDrawRect = *rectToErase;
  64.     else
  65.         destDrawRect = viewer->marqueeRect;
  66.  
  67.     if (EmptyRect(&destDrawRect))
  68.         return;
  69.     srcDrawRect = destDrawRect;
  70.  
  71.     OffsetRect(&srcDrawRect, -viewer->outputFrame.left,
  72.         -viewer->outputFrame.top);
  73.     // Map src rect to correct frame in viewer->buffer
  74.     OffsetRect(&srcDrawRect, 0, viewer->curFrame *
  75.         viewer->picsFrame.bottom);
  76.  
  77.     GetBackColor(&saveBack);
  78.     backColor.red = backColor.green = backColor.blue = 0xFFFF;
  79.     RGBBackColor(&backColor);
  80.     CopyGraphicsBuffer2Window(viewer->buffer, viewer->window,
  81.         (CP_Rect*)&srcDrawRect, (CP_Rect*)&destDrawRect);
  82.     RGBBackColor(&saveBack);
  83. } // END _EraseMarquee
  84.  
  85. // ---------------------------------------------------------------------------
  86.  
  87. /*
  88.     Call this to set the rect of the marquee. The marquee is not
  89.     drawn, however. Call _FrameMarquee() to do that.
  90.     If you pass NULL to <newMarquee> it sets the marquee rect
  91.     to empty (0,0,0,0)
  92. */
  93.  
  94. void _SetMarqueeRect(
  95.     PICSViewerData *viewer,
  96.     const Rect *newMarquee,
  97.     Boolean updateInfo) {
  98.  
  99.     if (EqualRect(newMarquee, &viewer->marqueeRect)) {
  100.         return;
  101.     }
  102.  
  103.     if (newMarquee != NULL)
  104.         viewer->marqueeRect = *newMarquee;
  105.     else
  106.         SetRect(&viewer->marqueeRect, 0, 0, 0, 0);
  107.  
  108.     if (updateInfo)
  109.         _UpdateMarqueeRectInfo(viewer);
  110. } // END _SetMarqueeRect
  111.  
  112. // ---------------------------------------------------------------------------
  113.  
  114. /*
  115.     This gives pertinent info on the marquee...
  116. */
  117.  
  118. void _UpdateMarqueeRectInfo(PICSViewerData *viewer) {
  119.     Str255 outputStr    = "\p[ Left: ";
  120.     Str15 topStr        = "\p | Top: ";
  121.     Str15 rightStr        = "\p | Right: ";
  122.     Str15 bottomStr        = "\p | Bottom: ";
  123.     Str15 widthStr        = "\p | W: ";
  124.     Str15 heightStr        = "\p | H: ";
  125.     Str15 endStr        = "\p ]";
  126.     Str15 numStr;
  127.     Rect marqueeRect;
  128.  
  129.     marqueeRect = viewer->marqueeRect;
  130.     // Compensate for viewer->outputFrame
  131.     OffsetRect(&marqueeRect, -viewer->outputFrame.left,
  132.         -viewer->outputFrame.top);
  133.  
  134.     NumToString(marqueeRect.left, numStr);
  135.     PStrCat(numStr, outputStr);
  136.     PStrCat(topStr, outputStr);
  137.     NumToString(marqueeRect.top, numStr);
  138.     PStrCat(numStr, outputStr);
  139.     PStrCat(rightStr, outputStr);
  140.     NumToString(marqueeRect.right, numStr);
  141.     PStrCat(numStr, outputStr);
  142.     PStrCat(bottomStr, outputStr);
  143.     NumToString(marqueeRect.bottom, numStr);
  144.     PStrCat(numStr, outputStr);
  145.     
  146.     PStrCat(widthStr, outputStr);
  147.     NumToString(marqueeRect.right - marqueeRect.left, numStr);
  148.     PStrCat(numStr, outputStr);
  149.     PStrCat(heightStr, outputStr);
  150.     NumToString(marqueeRect.bottom - marqueeRect.top, numStr);
  151.     PStrCat(numStr, outputStr);
  152.     PStrCat(endStr, outputStr);
  153.  
  154.     SetDItemText(viewer->window,
  155.         kPICSViewer_TrackCropField, outputStr);
  156. } // END _UpdateMarqueeRectInfo
  157.  
  158. // ---------------------------------------------------------------------------
  159.  
  160. /*
  161.     Either select everything or deselect everything.
  162. */
  163.  
  164. void _SelectEntirePICSViewerFrame(PICSViewerData *viewer, Boolean select) {
  165.     if (!viewer->trackMouse) {
  166.         SetDlogCtlValue(viewer->window, kPICSViewer_TrackMouseBtn, 1);
  167.         viewer->trackMouse = true;
  168.     }
  169.     
  170.     if (select) {
  171.         _SetMarqueeRect(viewer, &viewer->outputFrame, true);
  172.     }
  173.     else {
  174.         _SetMarqueeRect(viewer, NULL, false);
  175.         SetDItemText(viewer->window, kPICSViewer_TrackCropField, kEmptyStr);
  176.     }
  177.  
  178.     // Erase old marquee frame; idle proc will draw
  179.     // new marquee
  180.     _EraseMarquee(viewer, &viewer->outputFrame);
  181. }
  182.  
  183. // ---------------------------------------------------------------------------
  184.  
  185. void _ActionPICSViewer(PICSViewerData *viewer) {
  186.     if (viewer->trackMouse) {
  187.         Point mouseLoc;
  188.         Boolean validTrackRect;
  189.         Boolean insideTrackRect;
  190.  
  191.         // Is there a marquee?
  192.         validTrackRect = !EmptyRect(&viewer->marqueeRect);
  193.  
  194.         // If marquee exists, is mouse inside it?
  195.         GetMouse(&mouseLoc);
  196.         if (validTrackRect)
  197.             insideTrackRect = PtInRect(mouseLoc, &viewer->marqueeRect);
  198.         else
  199.             insideTrackRect = false;
  200.  
  201.         switch(viewer->currentAction) {
  202.             case kSelectionAction: {
  203.                 // Standard mouse click with no modifier keys pressed
  204.  
  205.                 // Erase current marquee, if any
  206.                 if (validTrackRect) {
  207.                     _EraseMarquee(viewer, NULL);
  208.                     _SetMarqueeRect(viewer, NULL, false);
  209.                 }
  210.                 SetPort(viewer->window);
  211.                 GetMouse(&mouseLoc);
  212.  
  213.                 if (PtInRect(mouseLoc, &viewer->outputFrame)) {
  214.                     // Anchor coordinates of topleft of
  215.                     // tracking rect first before calling
  216.                     // TrackMarquee.
  217.  
  218.                     TrackMarqueeOpaque(mouseLoc,
  219.                         (TrackUpdateProc)_TrackUpdateMarquee, &sMarqueeColor,
  220.                         &viewer->outputFrame, &viewer->marqueeRect);
  221.                 }
  222.                 
  223.                 if (EmptyRect(&viewer->marqueeRect)) {
  224.                     SetDItemText(viewer->window,
  225.                         kPICSViewer_TrackCropField, kEmptyStr);
  226.                 }
  227.             } break;
  228.             
  229.             case kCompositeAction: {
  230.                 if (insideTrackRect) {
  231.                     SetCursor(&qd.arrow);
  232.                     _CompositePICSViewer(viewer);
  233.                 }
  234.             } break;
  235.             
  236.             case kLeftAdjustSelectionAction:
  237.             case kRightAdjustSelectionAction: {
  238.                 long dummy;
  239.                 Rect adjustedRect = viewer->marqueeRect;
  240.  
  241.                 while (StillDown()) {
  242.                     GetMouse(&mouseLoc);
  243.                     _EraseMarquee(viewer, NULL);
  244.  
  245.                     ConstrainPointWithinRect(&mouseLoc, &viewer->outputFrame);
  246.                     if (viewer->currentAction == kLeftAdjustSelectionAction) {
  247.                         if (mouseLoc.h >= adjustedRect.right) {
  248.                             mouseLoc.h = adjustedRect.right - 1;
  249.                         }
  250.                         adjustedRect.left = mouseLoc.h;
  251.                     }
  252.                     else {
  253.                         if (mouseLoc.h <= adjustedRect.left) {
  254.                             mouseLoc.h = adjustedRect.left + 1;
  255.                         }
  256.                         adjustedRect.right = mouseLoc.h;
  257.                     }
  258.  
  259.                     FrameMarquee(&adjustedRect, &sMarqueeColor);
  260.                     _SetMarqueeRect(viewer, &adjustedRect, true);
  261.                     Delay(MARQUEE_DELAY, &dummy);
  262.                 }
  263.             } break;
  264.  
  265.             case kTopAdjustSelectionAction:
  266.             case kBottomAdjustSelectionAction: {
  267.                 long dummy;
  268.                 Rect adjustedRect = viewer->marqueeRect;
  269.  
  270.                 while (StillDown()) {
  271.                     GetMouse(&mouseLoc);
  272.                     _EraseMarquee(viewer, NULL);
  273.  
  274.                     ConstrainPointWithinRect(&mouseLoc, &viewer->outputFrame);
  275.                     if (viewer->currentAction == kTopAdjustSelectionAction) {
  276.                         if (mouseLoc.v >= adjustedRect.bottom) {
  277.                             mouseLoc.v = adjustedRect.bottom - 1;
  278.                         }
  279.                         adjustedRect.top = mouseLoc.v;
  280.                     }
  281.                     else {
  282.                         if (mouseLoc.v <= adjustedRect.top) {
  283.                             mouseLoc.v = adjustedRect.top + 1;
  284.                         }
  285.                         adjustedRect.bottom = mouseLoc.v;
  286.                     }
  287.  
  288.                     FrameMarquee(&adjustedRect, &sMarqueeColor);
  289.                     _SetMarqueeRect(viewer, &adjustedRect, true);
  290.                     Delay(MARQUEE_DELAY, &dummy);
  291.                 }
  292.             } break;
  293.             
  294.             case kMoveSelectionAction: {
  295.                 long dummy;
  296.                 Rect dragRect = viewer->marqueeRect;
  297.                 short offsetH, offsetV;
  298.  
  299.                 if (insideTrackRect) {
  300.                     SetCursor(*GetCursor(kHandClosedCursorID));
  301.  
  302.                     // Assumes mouse is INSIDE tracking rect
  303.                     // & thus to right & below of topLeft of rect
  304.                     offsetH = mouseLoc.h - viewer->marqueeRect.left;
  305.                     offsetV = mouseLoc.v - viewer->marqueeRect.top;
  306.  
  307.                     while (StillDown()) {
  308.                         GetMouse(&mouseLoc);
  309.                         _MovePICSViewerSelection(viewer, mouseLoc,
  310.                             offsetH, offsetV);
  311.                         Delay(MARQUEE_DELAY, &dummy);
  312.                     }
  313.  
  314.                     if (EmptyRect(&viewer->marqueeRect)) {
  315.                         SetDItemText(viewer->window,
  316.                             kPICSViewer_TrackCropField, kEmptyStr);
  317.                     }
  318.                 }
  319.             } break;
  320.             
  321.             case kNoAction:
  322.                 // Mouse click in gray area. De-select marquee
  323.                 if (validTrackRect) {
  324.                     _EraseMarquee(viewer, NULL);
  325.                     _SetMarqueeRect(viewer, NULL, true);
  326.                     SetDItemText(viewer->window,
  327.                         kPICSViewer_TrackCropField, kEmptyStr);
  328.                 }
  329.             break;
  330.         }
  331.     }
  332. } // END _ActionPICSViewer
  333.  
  334. // ---------------------------------------------------------------------------
  335.  
  336. void _MovePICSViewerSelection(
  337.     PICSViewerData *viewer,
  338.     Point mouseLoc,
  339.     short offsetH,
  340.     short offsetV) {
  341.  
  342.     Rect moveRect = viewer->marqueeRect;
  343.     
  344.     _EraseMarquee(viewer, NULL);
  345.  
  346.     ConstrainPointWithinRect(&mouseLoc, &viewer->outputFrame);
  347.     MoveRectTo(&moveRect,
  348.         mouseLoc.h-offsetH, mouseLoc.v-offsetV);
  349.     
  350.     // Confine marquee to outputFrame
  351.     if (moveRect.left < viewer->outputFrame.left) {
  352.         OffsetRect(&moveRect, (viewer->outputFrame.left -
  353.             moveRect.left), 0);
  354.     }
  355.     else if (moveRect.right > viewer->outputFrame.right) {
  356.         OffsetRect(&moveRect, (viewer->outputFrame.right -
  357.             moveRect.right), 0);
  358.     }
  359.     if (moveRect.top < viewer->outputFrame.top) {
  360.         OffsetRect(&moveRect, 0, (viewer->outputFrame.top -
  361.             moveRect.top));
  362.     }
  363.     else if (moveRect.bottom > viewer->outputFrame.bottom) {
  364.         OffsetRect(&moveRect, 0, (viewer->outputFrame.bottom -
  365.             moveRect.bottom));
  366.     }
  367.  
  368.     if (EmptyRect(&moveRect)) {
  369.         // Could be "negative space" rect, so clear it
  370.         SetRect(&moveRect, 0, 0, 0, 0);
  371.     }
  372.     
  373.     FrameMarquee(&moveRect, &sMarqueeColor);
  374.     _SetMarqueeRect(viewer, &moveRect, true);
  375. } // END _MovePICSViewerSelection
  376.  
  377. // ---------------------------------------------------------------------------
  378.  
  379. void _ResizePICSViewerSelection(PICSViewerData *viewer, const Rect *newMarquee) {
  380.     _EraseMarquee(viewer, NULL);
  381.     FrameMarquee(newMarquee, &sMarqueeColor);
  382.     _SetMarqueeRect(viewer, newMarquee, true);
  383. } // END _ResizePICSViewerSelection
  384.  
  385. // ---------------------------------------------------------------------------
  386.  
  387. void _KeyDownPICSViewerSelection(PICSViewerData *viewer, char keyPressed) {
  388.     Rect adjustedRect = viewer->marqueeRect;
  389.     
  390.     if (SHRINKSELECTION_SHORTCUT) {
  391.         switch(keyPressed) {
  392.             case kLeftArrow_Key:
  393.                 adjustedRect.right--;
  394.                 if (adjustedRect.right <= adjustedRect.left)
  395.                     adjustedRect.right = adjustedRect.left + 1;
  396.             break;
  397.             case kRightArrow_Key:
  398.                 adjustedRect.left++;
  399.                 if (adjustedRect.left >= adjustedRect.right)
  400.                     adjustedRect.left = adjustedRect.right - 1;
  401.             break;
  402.             case kUpArrow_Key:
  403.                 adjustedRect.bottom--;
  404.                 if (adjustedRect.bottom <= adjustedRect.top)
  405.                     adjustedRect.bottom = adjustedRect.top + 1;
  406.             break;
  407.             case kDownArrow_Key:
  408.                 adjustedRect.top++;
  409.                 if (adjustedRect.top >= adjustedRect.bottom)
  410.                     adjustedRect.top = adjustedRect.bottom - 1;
  411.             break;
  412.         }
  413.  
  414.             _ResizePICSViewerSelection(viewer, &adjustedRect);
  415.     }
  416.     else if (GROWSELECTION_SHORTCUT) {
  417.         switch(keyPressed) {
  418.             case kLeftArrow_Key:
  419.                 adjustedRect.left--;
  420.             break;
  421.             case kRightArrow_Key:
  422.                 adjustedRect.right++;
  423.             break;
  424.             case kUpArrow_Key:
  425.                 adjustedRect.top--;
  426.             break;
  427.             case kDownArrow_Key:
  428.                 adjustedRect.bottom++;
  429.             break;
  430.         }
  431.  
  432.         // Keep new marquee within bounds of PICS
  433.         if (adjustedRect.left < viewer->outputFrame.left)
  434.             adjustedRect.left = viewer->outputFrame.left;
  435.         if (adjustedRect.right > viewer->outputFrame.right)
  436.             adjustedRect.right = viewer->outputFrame.right;
  437.         if (adjustedRect.top < viewer->outputFrame.top)
  438.             adjustedRect.top = viewer->outputFrame.top;
  439.         if (adjustedRect.bottom > viewer->outputFrame.bottom)
  440.             adjustedRect.bottom = viewer->outputFrame.bottom;
  441.         _ResizePICSViewerSelection(viewer, &adjustedRect);
  442.     }
  443.     else {
  444.         short increment;
  445.         Point movedPoint;
  446.  
  447.         if (!LARGERINCREMENT_SHORTCUT)
  448.             increment = kUsualMoveIncrement;
  449.         else
  450.             increment = kLargerMoveIncrement;
  451.  
  452.         switch(keyPressed) {
  453.             case kLeftArrow_Key:
  454.                 OffsetRect(&adjustedRect, -increment, 0);
  455.             break;
  456.             case kRightArrow_Key:
  457.                 OffsetRect(&adjustedRect, increment, 0);
  458.             break;
  459.             case kUpArrow_Key:
  460.                 OffsetRect(&adjustedRect, 0, -increment);
  461.             break;
  462.             case kDownArrow_Key:
  463.                 OffsetRect(&adjustedRect, 0, increment);
  464.             break;
  465.         } // END inner switch
  466.         
  467.         movedPoint.h = adjustedRect.left;
  468.         movedPoint.v = adjustedRect.top;
  469.         _MovePICSViewerSelection(viewer, movedPoint, 0, 0);
  470.     }
  471. }
  472.  
  473. // ---------------------------------------------------------------------------
  474.  
  475. void _FrameMarquee(PICSViewerData *viewer) {
  476.     FrameMarquee(&viewer->marqueeRect, &sMarqueeColor);
  477. } // END _FrameMarquee